﻿namespace Game {
	class Window {
		
		// width
		field _w;

		// height
		field _h;

		// screen object
		field _s;

		// native window instance
		field _0;

		// background box
		// TODO: is this necessary? or is this a bug that requires me to have this?
		field _b;

		constructor(width, height, fps, fullscreen) {
			argmatch(INT, INT, INT, BOOL) {
				if (width > 0 && height > 0 && fps > 0) {
					t = @game_window_ctor();
					this._0 = t;
					this._w = width;
					this._h = height;
					this._s = new Game.Screen(this._0, width, height);
					this._b = new Game.Image(width, height);
					this._b.fill(0, 0, 0, 255);
					return;
				}
			}
			throw new IllegalArgumentException();
		}

		property width { get { return this._w; } }
		property height { get { return this._h; } }

		abstract method update();

		abstract method render(screen);

		method start() {
			@game_window_start(this._0, this._nativeUpdate, this._nativeRender);
		}

		method _nativeUpdate() {
			this.update();
		}

		method _nativeRender() {
			this._s._b.clear();
			this._s.blit(this._b, 0, 0);
			this.render(this._s);
			@game_window_blit_screen(this._0, this._s._b);
		}

		method close() {
			@game_window_close(this._0, this._s);
		}

		method pumpEvents() {
			output = [];
			
			do {
				e = @game_window_pop_event(this._0);
				if (e != null) {
					e = new Game.Event(
						e[0], // type (string)
						e[1], // key code (int?)
						e[2], // down (bool?)
						e[3], // mouse button (int?)
						e[4], // x (int?)
						e[5], // y (int?)
						e[6] // amount (int?)
						);
					output.add(e);
				}
			} while (e != null);

			return output;
		}
	}
}
